
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Slf4j
public class AliyunOSS {

    private final static String bucketName = "bucketName";
    private final static String ACCESS_KEY = "ACCESS_KEY";
    private final static String SECRET_KEY = "SECRET_KEY";
    private final static String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    private final static String region = "cn-hangzhou";

    public static final String URL = "https://{bucketName}.oss-cn-hangzhou.aliyuncs.com/";

    private final static DefaultCredentialProvider credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider(ACCESS_KEY, SECRET_KEY);
    private final static ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();

    static {
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
    }

    public static String upload(MultipartFile file, String path, String fileName) throws IllegalStateException {
        String objectName = path + "/" + fileName;
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file.getInputStream());
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            // if (result.getResponse().isSuccessful()) {
            //     return result.getResponse().getUri();
            // }
            return URL + objectName;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered a serious internal problem while trying to communicate with OSS, such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        } catch (IOException e) {
            log.error("Error Message:" + e.getMessage());
        } finally {
            ossClient.shutdown();
        }

        return "";
    }

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        DefaultCredentialProvider credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider(ACCESS_KEY, SECRET_KEY);
        // 填写Bucket名称，例如examplebucket。
        String bucketName = "bucketName";
        // 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String objectName = "xsz/test.jpg";
        // 填写本地文件的完整路径，例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        String filePath = "D:\\xsz.jpg";
        // 填写Bucket所在地域。以华东1（杭州）为例，Region填写为cn-hangzhou。
        String region = "cn-hangzhou";

        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
            // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    //
    // /**
    //  * 生成一个唯一的 Bucket 名称
    //  */
    // public static String generateUniqueBucketName(String prefix) {
    //     // 获取当前时间戳
    //     String timestamp = String.valueOf(System.currentTimeMillis());
    //     // 生成一个 0 到 9999 之间的随机数
    //     Random random = new Random();
    //     int randomNum = random.nextInt(10000); // 生成一个 0 到 9999 之间的随机数
    //     // 连接以形成一个唯一的 Bucket 名称
    //     return prefix + "-" + timestamp + "-" + randomNum;
    // }
    //
    // public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException {
    //     // 设置 OSS Endpoint 和 Bucket 名称
    //     String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    //     String bucketName = generateUniqueBucketName("demo");
    //     // 替换为您的 Bucket 区域
    //     String region = "cn-hangzhou";
    //     // 创建 OSSClient 实例
    //     EnvironmentVariableCredentialsProvider credentialsProvider =
    //             CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
    //     OSS ossClient = OSSClientBuilder.create()
    //             .endpoint(endpoint)
    //             .credentialsProvider(credentialsProvider)
    //             .region(region)
    //             .build();
    //     try {
    //         // 1. 创建存储空间（Bucket）
    //         ossClient.createBucket(bucketName);
    //         System.out.println("1. Bucket " + bucketName + " 创建成功。");
    //         // 2. 上传文件
    //         String objectName = "exampledir/exampleobject.txt";
    //         String content = "Hello OSS";
    //         ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
    //         System.out.println("2. 文件 " + objectName + " 上传成功。");
    //         // 3. 下载文件
    //         OSSObject ossObject = ossClient.getObject(bucketName, objectName);
    //         InputStream contentStream = ossObject.getObjectContent();
    //         BufferedReader reader = new BufferedReader(new InputStreamReader(contentStream));
    //         String line;
    //         System.out.println("3. 下载的文件内容：");
    //         while ((line = reader.readLine()) != null) {
    //             System.out.println(line);
    //         }
    //         contentStream.close();
    //         // 4. 列出文件
    //         System.out.println("4. 列出 Bucket 中的文件：");
    //         ObjectListing objectListing = ossClient.listObjects(bucketName);
    //         for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
    //             System.out.println(" - " + objectSummary.getKey() + " (大小 = " + objectSummary.getSize() + ")");
    //         }
    //         // 5. 删除文件
    //         ossClient.deleteObject(bucketName, objectName);
    //         System.out.println("5. 文件 " + objectName + " 删除成功。");
    //         // 6. 删除存储空间（Bucket）
    //         ossClient.deleteBucket(bucketName);
    //         System.out.println("6. Bucket " + bucketName + " 删除成功。");
    //     } catch (OSSException oe) {
    //         System.out.println("Caught an OSSException, which means your request made it to OSS, "
    //                 + "but was rejected with an error response for some reason.");
    //         System.out.println("Error Message:" + oe.getErrorMessage());
    //         System.out.println("Error Code:" + oe.getErrorCode());
    //         System.out.println("Request ID:" + oe.getRequestId());
    //         System.out.println("Host ID:" + oe.getHostId());
    //     } catch (ClientException | IOException ce) {
    //         System.out.println("Caught an ClientException, which means the client encountered "
    //                 + "a serious internal problem while trying to communicate with OSS, "
    //                 + "such as not being able to access the network.");
    //         System.out.println("Error Message:" + ce.getMessage());
    //     } finally {
    //         if (ossClient != null) {
    //             ossClient.shutdown();
    //         }
    //     }
    // }

}
